﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace MvcHeatloss.Models
{
    //public enum RoomType { Square, Bay, Long, LShape } //later implementation

    //public enum Measure { Meters, Feet } //later implementation
    
    [MetadataType(typeof(RoomData))]
    public partial class Room: IEnumerable
    {
      
        private ProjectEntities db = new ProjectEntities();

        //Constructor
        public Room(double airMov, int temp, double height, double length, double width, int noOfWalls)
        {
            ProjectEntities db = new ProjectEntities();
            
            // set the H X W x L proprties etc.
            this.Width = (decimal)width;
            this.Length = (decimal)length;
            this.Height = (decimal)height;
            this.TemperatureDifference = temp;
            this.AirMovements = (decimal)airMov;
            this.NoOfWalls = noOfWalls;

            // Default: internal ceiling, external floor, standard single glazed windows, 4 walls (2 external insulated)
            string defaultCeilingType = "Internal Ceiling";
            string defaultFloorType = "Un-insulated Floor";
            string defaultWindowType = "Single Glazed Window";
            string defaultExtWallType = "50mm cavity Wall (Insulated)";
            string defaultIntWallType = "Internal Wall";
            double windowPercentage = 0.4;
            double windowStdHeight = 1.2;
            int defaulNoOfWalls = noOfWalls;

            // no outside doors or skylights
            this.RoomCeiling = new Ceiling((double)this.Length, (double)this.Width, defaultCeilingType, this.TemperatureDifference);
            this.RoomDoors = new Door();
            this.RoomDoors.DoorHeatloss = 0.0;
            this.RoomSkylights = new Skylight();
            this.RoomSkylights.SkylightHeatloss = 0.0;
            this.RoomFloor = new Floor((double)this.Length, (double)this.Width, defaultFloorType, this.TemperatureDifference);
            
            this.RoomVolume = CalcHeatoss.CalcVolume(height, length, width);
            this.RoomAirHeatloss = CalcHeatoss.AirHeatloss((double)this.RoomVolume, (double)this.AirMovements, this.TemperatureDifference);
            // construct a default window
            this.RoomWindows = new Window(windowStdHeight, ((double)this.Length * windowPercentage), defaultWindowType, this.TemperatureDifference);
            // construct default walls
            this.RoomWalls = new Wall[defaulNoOfWalls];
            for (int i = 0; i < defaulNoOfWalls; i++)
            {
                if (i < (defaulNoOfWalls - 2))
                {
                    this.RoomWalls[i] = new Wall((double)this.Height, (double)this.Length, String.Format("{0}",
                        defaultIntWallType), String.Format("{0}", this.TemperatureDifference));
                }
                else
                {
                    this.RoomWalls[i] = new Wall((double)this.Height, (double)this.Width, String.Format("{0}",
                        defaultExtWallType), String.Format("{0}", this.TemperatureDifference));
                }
            }
            //Get the Heatloss set
            this.RequiredBTU = CalcHeatoss.TotalHeatCalc(this);
        }

        public Room()
        {
        }

        

        
        
        // DROP DOWN LISTS
        // list to use for drop down list for Air Changes
        public static double[] AirChangesList
        {
            get
            {
                return new double[] { 1.5, 1.0, 1.75, 2.0, 2.25, 2.5 };
            }
        }
        // air changes property (get from UValue table)
        public double airChanges = 1.5;

        // list to use for drop down list for Required Temperature
        public static int[] TemperatureDifferenceList
        {
            get
            {
                return new int[] { 21, 18, 19, 20, 22, 23, 24 };
            }
        }
        //list to se for Measurement type
        public static String[] MeasurementsList
        {
            get
            {
                return new String[] {"Meters", "Feet" };
            }
        }
        // list to see description of wall types
        public static String[] WallTypeList
        {
            get
            {
                return new String[] { "50mm cavity Wall (un-Insulated)", "50mm cavity Wall (Insulated)", "50mm+ cavity Wall (un-Insulated)", 
                    "50mm+ cavity Wall (Insulated)", "Internal Wall" };  
            }
        }
        // list to see description of floor types
        public static String[] FloorTypeList
        {
            get
            {
                return new String[] { "Un-insulated Floor", "Insulated Floor", "Internal Floor" };
            }
        }
        // list to see description of ceiling types
        public static String[] CeilingTypeList
        {
            get
            {
                return new String[] { "Un-insulated Ceiling", "Ceiling with Light Insulation","Ceiling with Medium Insulation", "Ceiling with Heavy Insulation", "Internal Ceiling" };
            }
        }
        // list to see description of window types
        public static String[] WindowTypeList
        {
            get
            {
                return new String[] { "Single Glazed Window", "Double/Triple Glazed Window" };
            }
        }
        // list to see description of door types
        public static String[] DoorTypeList
        {
            get
            {
                return new String[] { "Steel Door", "Wood/PVC Door", "Internal Door"  };
            }
        }
        // list to see description of skylight types
        public static String[] SkylightTypeList
        {
            get
            {
                return new String[] { "Single Glazed Skylight", "Double Glazed Skylight" };
            }
        }
        // list of number of walls 4,6,8
        public static int[] NoOfWallsList
        {
            get
            {
                return new int[] { 4, 6, 8 };
            }
        }
        
        
        //PROPERTIES
        //meters or feet
        public String Measurement { get; set; }

        // I want to use advanced heatloss calculation
        public bool Advanced { get; set; }

        // Do you want to enter UValue manually
        public bool MyUValues { get; set; }


        // set temperature difference
        const int outsideTemp = -4;
        int temperatureDifference;
        public int TemperatureDifference
        {
            get
            {
                return temperatureDifference;
            }
            set
            {
                temperatureDifference = value - outsideTemp;
            }
        }
        
        // Room type property
        //public RoomType RoomType { get; set; }


        // Floor
        public Floor RoomFloor { get; set; }

        //Ceiling
        public Ceiling RoomCeiling { get; set; }

        //number of walls
        public int NoOfWalls { get; set; }

        // Walls
        public Wall[] roomWalls;
        public Wall[] RoomWalls { get; set; }

        // Doors
        public Door RoomDoors { get; set; }

        // Windows
        public Window RoomWindows { get; set; }

        //Skylights
        public Skylight RoomSkylights { get; set; }
        
        // Volumme
        double roomVolume;
        public double RoomVolume 
        {
            get
            {
                return roomVolume;
            }
            set
            {
                roomVolume = value;
            }
        }
        
        //Air
        double roomAirHeatloss;
        public double RoomAirHeatloss 
        {
            get
            {
                return roomAirHeatloss;
            }
            set
            {
                roomAirHeatloss = value;
            }
        }


        
        // METHODS
        //public int GetQuickHeatloss(double length, double width, double height)
        //{
        //    ProjectEntities db = new ProjectEntities();

        //    // get U Value from database
        //    double uValue = Convert.ToDouble(db.UValues.Where(uval => uval.TypeID == "Test").Select(uval => uval.UValue1).First());

        //    // heat lost through walls
        //    double wall1 = (length * height) * uValue * TemperatureDifference;
        //    double wall2 = (width * height) * uValue * TemperatureDifference;
        //    double wall3 = (length * height) * uValue * TemperatureDifference;
        //    double wall4 = (width * height) * uValue * TemperatureDifference;

        //    // heat lost through floor
        //    double floor = (length * width) * uValue * TemperatureDifference;

        //    // heat lost through ceiling
        //    double ceiling = (length * width) * uValue * TemperatureDifference;

        //    // ventilation heat lost
        //    double air = (width * height * length) * uValue * TemperatureDifference * airChanges;

        //    double heatLoss = wall1 + wall2 + wall3 + wall4 + floor + ceiling + air;

        //    return (int)heatLoss;

        //}

        public IEnumerator GetEnumerator()
        {
            for(int i = 0; i < NoOfWalls; i++)
            {
                yield return RoomWalls[i];
            }
        }

    }

    // metadata class for Student (partial definitions here and in StudentModel.Designer.cs
    public class RoomData
    {
        [Display(Name = "Room Length in meters")]
        public decimal Length { get; set; }

        [Display(Name = "Room Width in meters")]
        public decimal Width { get; set; }

        [Display(Name = "Room Height in meters")]
        public decimal Height { get; set; }

        [Display(Name = "Air Movements")]
        public decimal AirMovements { get; set; }

        [Display(Name = "Required BTU")]
        public decimal RequiredBTU { get; set; }

        [Display(Name = "Room Temperature Required (in Degrees Centigrade)")]
        public decimal TemperatureDifference { get; set; }

    }
}